using System;
using System.Collections.Generic;
using System.Configuration;
using System.Web;
using DotNetNuke;
using WGR_Business  = DotNetWarcraft.WoWGuildRoster.Business;

namespace DotNetWarcraft.WoWGuildRoster.UI.DNN {
  public class ArmoryService : DotNetNuke.Services.Scheduling.SchedulerClient {
    protected int _exceptionCount;

    public ArmoryService(DotNetNuke.Services.Scheduling.ScheduleHistoryItem objScheduleHistoryItem)
      : base() {
      this.ScheduleHistoryItem = objScheduleHistoryItem;
    }

    public override void DoWork() {
      try {
        this.Progressing();

        String _vers = WGR_Business.DnnGuildRosterController.VersionNumber;
        //List<WGR_Business.GuildRoster> _rosters = WGR_Business.DnnGuildRosterController.GetRosters();

        //foreach (WGR_Business.GuildRoster _roster in _rosters) {
        //  WGR_Business.LoadArmoryRoster _loadArmory = new WGR_Business.LoadArmoryRoster(_roster.Roster_ID);
        //  _loadArmory.Execute();
        //}

        _exceptionCount = 0;

        LoadRosters();
        LoadCharEntries();


        this.ScheduleHistoryItem.AddLogNote("Roster Index Build Succeeded");
        this.ScheduleHistoryItem.Succeeded = true;
      } catch (Exception exExc) {
        this.ScheduleHistoryItem.Succeeded = false;
        this.ScheduleHistoryItem.AddLogNote("Roster Index Build Failed. Type: '" +
          exExc.GetType().ToString() + "'; Message: " + exExc.Message.ToString());
        this.Errored(ref exExc);
      } finally {
        WGR_Business.DnnGuildRosterController.ProtectLocalCache = false;
      }
    }

    protected void LoadRosters() {
      List<WGR_Business.GuildRoster> _rosters = WGR_Business.DnnGuildRosterController.GetRosters();

      foreach (WGR_Business.GuildRoster _roster in _rosters) {
        WGR_Business.LoadArmoryRoster _loadArmory = new WGR_Business.LoadArmoryRoster(_roster.Roster_ID);
        _loadArmory.Execute();
      }
    }

    protected void LoadCharEntries() {
      int _lastProcessedChar = -1;
      int _numOfCharsToProcess = -1;

      //Get the current Data load for characters
      WGR_Business.DataLoad _load = WGR_Business.DnnGuildRosterController.GetDataLoad_CurrentCharLoad();

      //Iterate through characters, passing the data load
      if (_numOfCharsToProcess < 1) {
        //Process all characters
        List<WGR_Business.GuildEntry> _entries = WGR_Business.DnnGuildRosterController.GetCharEntries();
        foreach (WGR_Business.GuildEntry _entry in _entries) {
          if (_entry.Current_Flag > 0) {
            LoadCharEntry(_entry.Char_ID, ref _load);
          }
        }
        //Pass in a -1 char id to close out the load
        LoadCharEntry(-1, ref _load);

      } else {
        //Process the number of characters specified
        for (int _c = 0; _c < _numOfCharsToProcess; _c++) {
          if (_load == null) {
            _lastProcessedChar = -1;
          } else {
            _lastProcessedChar = _load.LastCharIdLoaded;
          }

          WGR_Business.GuildEntry _entry = WGR_Business.DnnGuildRosterController.GetCharEntry_NextValid(_lastProcessedChar);
          LoadCharEntry(_entry.Char_ID, ref _load);
        }
      }
    }
    protected void LoadCharEntry(int charID, ref WGR_Business.DataLoad load) {
      if (charID < 0 && load != null) {
        //If we've ended our character processing run (no valid character was returned),
        //  then let's mark the load as complete
        load.LoadStatus_Enum = DotNetWarcraft.WoWGuildRoster.Business.WGR_LoadStatus.LoadedSuccessfully;
        WGR_Business.DnnGuildRosterController.UpdateDataLoad(load);
        load = null;
      } else {
        WGR_Business.LoadArmoryCharEntry _loadArmory;
        if (load == null && charID > 0) {
          _loadArmory = new WGR_Business.LoadArmoryCharEntry(charID);
          load = _loadArmory.LoadEntry;
        } else {
          _loadArmory = new WGR_Business.LoadArmoryCharEntry(charID, load);
        }
        try {
          _loadArmory.Execute();
          System.Threading.Thread.Sleep(WGR_Business.WGRDnnConstants.SETTING_SLEEP_BETWEEN_ARMORY_PULLS);

        } catch (System.Net.WebException _e) {
          // If we've encountered more than 10 of these errors, back off for this pull
          // ...and let's increment the count while we check
          if (_exceptionCount++ > 10) {
            throw _e;
          } else {
            // Otherwise, let's wait progressively longer between pulls
            System.Threading.Thread.Sleep(WGR_Business.WGRDnnConstants.SETTING_SLEEP_BETWEEN_ARMORY_PULLS * (5 * _exceptionCount));
          }
        } catch (Exception _e) {
          throw _e;
        }
      }

    }

  }

}
